package pub.tbc.rubbish.client.discovery;

import com.google.common.collect.Maps;
import pub.tbc.toolkit.Objs;

import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * 软负载助手类，暂时只提供简单随机和轮洵，有时间再实现加权
 *
 * @author tbc on 2016/12/9 17:14.
 */
public class LoadBalancingHelper {
    // 轮洵状态
    private static final Map<String, Integer> rotateIndexMap = Maps.newConcurrentMap();

    private static synchronized String ReturnResultAndUpdateRotateStatus(String serviceName, List<String> addresses) {
        Integer rotateIndex = rotateIndexMap.get(serviceName);
        // 因为轮洵序号的++操作放在下面提取集合元素时，此处判断时要用元素数-1
        if (Objs.isEmpty(rotateIndex) || rotateIndex >= addresses.size() - 1) {
            rotateIndexMap.put(serviceName, 0);
            return addresses.get(0);
        }
        rotateIndexMap.put(serviceName, ++rotateIndex);
        return addresses.get(rotateIndex);
    }

    /**
     * 简单随机
     *
     * @return .
     */
    public static String simpleRandom(List<String> addresses) {
        if (Objs.isEmpty(addresses)) {
            return null;
        }
        int serviceIndex = new Random().nextInt(addresses.size());
        return addresses.get(serviceIndex);
    }

    /**
     * 简单轮洵<br>
     * 当addresses发生变化时，该方法不是很公平
     *
     * @param addresses .
     * @return address
     */
    public static String rotate(String serviceName, List<String> addresses) {
        if (Objs.isEmpty(serviceName)) {
            throw new RuntimeException("serviceName cannot be empty");
        }
        if (Objs.isEmpty(addresses)) {
            return null;
        }
        return ReturnResultAndUpdateRotateStatus(serviceName, addresses);
    }
}
